home *** CD-ROM | disk | FTP | other *** search
/ MacWorld 1998 October / Macworld (1998-10).dmg / Shareware World / Info / For Developers / MacZoop 1.8.4 / More Classes / Threads / ZThread.h < prev    next >
Encoding:
C/C++ Source or Header  |  1998-07-22  |  4.2 KB  |  140 lines  |  [TEXT/CWIE]

  1. /*************************************************************************************************
  2. *
  3. *
  4. *            ObjectMacZapp        -- a standard Mac OOP application template
  5. *
  6. *
  7. *
  8. *            ZThread.h            -- an object that implements a single thread of execution.
  9. *
  10. *
  11. *
  12. *
  13. *
  14. *            © 1996, Graham Cox
  15. *
  16. *
  17. *
  18. *
  19. *************************************************************************************************/
  20.  
  21.  
  22. #pragma once
  23.  
  24.  
  25. #ifndef __ZTHREAD__
  26. #define __ZTHREAD__
  27.  
  28. #include     <Threads.h>
  29. #include    "ZErrors.h"
  30.  
  31. class    ZThread
  32. {
  33. protected:
  34.     
  35.     Boolean     fDone;
  36.     ThreadID     itsID;
  37.     Size        itsStack;
  38.     long         itsPeriod;
  39.     
  40. public:
  41.  
  42.     ZThread( long doPeriod = 0, Size stackSize = 0 );        // Constructor
  43.     virtual ~ZThread();                                        // Destructor
  44.     
  45.     // Do() is called by ThreadEntry() every doPeriod ticks.  This is the default 
  46.     // behaviour for a thread.  If you want something more complex, override ThreadEntry()  
  47.     virtual void Do() {};
  48.     
  49.     // ThreadEntry is the general entry point for the thread.  You should only override
  50.     // this if you don't want to use the default behaviour of calling Do() 
  51.     // periodically (e.g. async I/O perhaps).
  52.     //
  53.     // If you do override ThreadEntry() you must call one of the Yield functions
  54.     // every so often to let all the other threads get a look in.
  55.     virtual void ThreadEntry();   
  56.  
  57.     // SwitchingIn is called just before your thread is switched in to allow
  58.     // you to perform additional context setup (e.g. GrafPorts)
  59.     virtual void SwitchingIn() {};                             
  60.  
  61.     // SwitchingOut is called just before your thread is switched out to allow
  62.     // you to save extra context data.
  63.     virtual void SwitchingOut() {};                              
  64.  
  65.     // IsDone decides whether or not you have finished.  By default this
  66.     // returns fDone.
  67.     //
  68.     // This is used to exit the loop that keeps calling Do() - when IsDone returns
  69.     // TRUE, the thread will finish and terminate.
  70.     virtual inline Boolean IsDone();                                
  71.  
  72.     // SetDoPeriod() allows you to adjust the interval that Do() is called at
  73.     void SetDoPeriod( long doPeriod = 0 );
  74.  
  75.     // Start() actually creates the thread and sets it running
  76.     virtual void Start();                                    
  77.     
  78.     // Stop() stops a thread.  It can be restarted with Restart()
  79.     virtual OSErr Stop();    
  80.     
  81.     // Restart() puts a thread into the Ready state, restarting it after a Stop()                                
  82.     virtual OSErr Restart();
  83.     
  84.     // Terminate() kills a thread
  85.     virtual void Terminate( Boolean fReturnToPool = FALSE );
  86.  
  87.     // GetState() returns current thread state in *pState
  88.     // The states are defined in Threads.h but can be a bit confusing.
  89.     //
  90.     // Basically my understanding is:
  91.     //
  92.     // - kReadyThreadState means that the thread is ready to run but is not the current
  93.     //   thread.  Normal running threads will return this if GetState() is called from
  94.     //   another thread.
  95.     //
  96.     // - kStoppedThreadState means that the thread has been stopped by a Stop() instruction.
  97.     //
  98.     // - kRunningThreadState means that the thread is running *and* is the current thread.
  99.     //   GetState() will return this if it's called from within Do() say.
  100.     //
  101.     ThreadState GetState();
  102.  
  103.     // Returns thread ID
  104.     inline ThreadID GetThreadID()                                 
  105.     {
  106.         return itsID;
  107.     }                    
  108.     
  109.     // Returns available stack space in *freeStack
  110.     void GetStackSpace( unsigned long *freeStack )
  111.     {
  112.         FailOSErr( ThreadCurrentStackSpace( itsID, freeStack) );
  113.     }
  114.  
  115.     // Sleep for ticksToSleep ticks
  116.     virtual void SleepTicks( long ticksToSleep );                        
  117. };
  118.  
  119.  
  120. // ThreadEntryGlue is required because you can't pass a pointer to a virtual member
  121. // function to NewThread - calling a member function implicitly passes a pointer to
  122. // the object + a virtual function cannot be declared as pascal.
  123. //
  124. // Instead, NewThread gets a pointer to ThreadEntryGlue and ThreadEntryGlue calls
  125. // ThreadEntry in the object.  This is possible because ThreadEntryGlue gets a pointer
  126. // to the object as its parameter (otherwise it wouldn't know which object to call!
  127. pascal void * ThreadEntryGlue( ZThread* me );   
  128.  
  129. // SwitchingInGlue() and SwitchingOutGlue() are needed for similar reasons to above.
  130. pascal void SwitchingInGlue( ThreadID threadBeingSwitched, ZThread* me );
  131. pascal void SwitchingOutGlue( ThreadID threadBeingSwitched, ZThread* me );
  132.  
  133. // Utility function - yield for lTicks ticks
  134. void YieldTicks( long lTicks );
  135.  
  136. // Utility function - safe yield
  137. void SafeYield();
  138.  
  139.  
  140. #endif